﻿using System;
using System.Collections.Generic;
////using System.Linq;
using System.Text;
using System.Collections.Specialized;
using System.Drawing;
using System.Windows.Forms;
using Fireball.Windows.Forms;
using Fireball.Syntax;
using Fireball.CodeEditor.SyntaxFiles;
using DBConnectionLib;

namespace DBSourceToolsLib.SysObjects
{
    public class SOFunction : SysObject//, Interfaces.IDisplayPanel
    {
        protected DataSets.TableColumnsDS m_oColumnListDs = new DBSourceToolsLib.DataSets.TableColumnsDS();

        public SOFunction(string strName, string strBaseDirectory, Database oDatabase, string strUrn)
            : base(strName, strBaseDirectory, oDatabase, SysObjectType.Function)

        {
            this.Urn = strUrn;
            //LoadScript(oDatabase);
        }
        public SOFunction(string strFileName, Database oDatabase)
            : base(SysObjectType.Function, strFileName, oDatabase)
        {
//            Console.WriteLine("load SOFunction from " + strFileName);
            // we are loading this from disk - ensure we load columns from disk as well.
            string strColFileName = this.BaseDirectory + "\\Functions\\Columns\\" + this.Name + "_Columns.xml";
            if (System.IO.File.Exists(strColFileName))
                this.m_oColumnListDs.ReadXml(strColFileName);

        }

        public SOFunction(SysObject oldSysObject, Database targetDatabase)
            :base ( oldSysObject.Name, targetDatabase.BaseDirectory, targetDatabase, SysObjectType.Function)
        {
            this.Text = oldSysObject.Text;
            this.Text = this.Text.Replace("[" + oldSysObject.DBName + "]", "[" + targetDatabase.DatabaseName + "]");
        }

        public override void LoadScript(Database oDatabase, string strOutputFileName)
        {

        }

        #region IDisplayPanel Members

        public override System.Windows.Forms.Panel GetPanel()
        {
            Panel oPanel = new Panel();
            oPanel.Dock = DockStyle.Fill;

            CodeEditorControl codeEdit = new CodeEditorControl();
            codeEdit.Dock = DockStyle.Fill;

            CodeEditorSyntaxLoader.SetSyntax(codeEdit, SyntaxLanguage.SqlServer2K);
            codeEdit.Document.Text = this.Text;
            oPanel.Controls.Add(codeEdit);


            return oPanel;
        }

        #endregion



        internal void LoadScript(Database oDatabase, string strOutputFileName, Microsoft.SqlServer.Management.Smo.UserDefinedFunction oSmo)
        {
            base.EnsureDirectoryExists(strOutputFileName);

            Microsoft.SqlServer.Management.Smo.ScriptingOptions oScriptingOptions = new Microsoft.SqlServer.Management.Smo.ScriptingOptions();
            oScriptingOptions.ClusteredIndexes = true;
            oScriptingOptions.NonClusteredIndexes = true;
            oScriptingOptions.DriAll = true;
            oScriptingOptions.Indexes = true;
            oScriptingOptions.IncludeDatabaseContext = false;
            //oScriptingOptions.ExtendedProperties = true;
            // script the drop statement first.
            oScriptingOptions.ScriptDrops = true;
            oScriptingOptions.IncludeIfNotExists = true;
            oScriptingOptions.ExtendedProperties = UserSettings.Instance().UseExtendedProperties;
            oScriptingOptions.AnsiFile = UserSettings.Instance().UseANSII;

            StringCollection strDropColl = new StringCollection();
            strDropColl = oSmo.Script(oScriptingOptions);
            
            oScriptingOptions.ScriptDrops = false;
            oScriptingOptions.IncludeIfNotExists = false;
            oScriptingOptions.ExtendedProperties = UserSettings.Instance().UseExtendedProperties;
            oScriptingOptions.AnsiFile = UserSettings.Instance().UseANSII;

            oScriptingOptions.FileName = strOutputFileName;

            StringCollection myStrColl = new StringCollection();
            myStrColl = oSmo.Script(oScriptingOptions);

            base.AddDropScriptToFile(strOutputFileName, strDropColl);
            base.SetTextFromFile(strOutputFileName);

            foreach (Microsoft.SqlServer.Management.Smo.Parameter oCol in oSmo.Parameters)
            {
                DataSets.TableColumnsDS.TableColumnsRow newRow = m_oColumnListDs.TableColumns.NewTableColumnsRow();
                newRow.ColumnName = oCol.Name;
                newRow.Type = oCol.DataType.ToString();
                //oCol.DefaultValue
                m_oColumnListDs.TableColumns.AddTableColumnsRow(newRow);

            }

            m_oColumnListDs.AcceptChanges();

            string strColumnsFile = strOutputFileName.Substring(0, strOutputFileName.LastIndexOf("\\") + 1);
            strColumnsFile += "Columns\\" + this.Name + "_Columns.xml";
            base.EnsureDirectoryExists(strColumnsFile);
            FileUtils.EnsureFileIsWriteable(strColumnsFile);
            m_oColumnListDs.WriteXml(strColumnsFile);


        }

        public override Composite.DBComposite GetDBComposite()
        {
            //return new Composite.DBComposite(this.QualifiedName);

            // TODO : COMPLETE Add parameters to SOFunction
            Composite.DBComposite oFuncComposite = new Composite.DBComposite(this.Name, this.NameNoSchema, 
                Composite.DBCompositeType.Function,
                new Composite.TreeNodeTag(this.m_Database.NickName,
                "File", this.FileName, this.QualifiedName));

            if (this.Columns.Count > 0)
            {
                Composite.DBComposite oFieldsComposite =
                    new Composite.DBComposite("Parameters","Parameters",
                        Composite.DBCompositeType.Parameters,
                        new Composite.TreeNodeTag(this.m_Database.NickName,
                        "Parameters", this.Name, this.QualifiedName));

                oFuncComposite.Add(oFieldsComposite);

                foreach (ColInfo oColInfo in this.Columns)
                {
                    Composite.DBComposite oField = new Composite.DBComposite(oColInfo.NameAndType, oColInfo.Name,
                        Composite.DBCompositeType.Parameter,
                        new Composite.TreeNodeTag(this.m_Database.NickName, "Parameter", oColInfo.Name, null)
                        );
                    oFieldsComposite.Add(oField);
                }
            }

            return oFuncComposite;

        }

        public override List<ColInfo> Columns
        {
            get
            {
                List<ColInfo> strList = new List<ColInfo>();
                foreach (DBSourceToolsLib.DataSets.TableColumnsDS.TableColumnsRow oRow in
                    this.m_oColumnListDs.TableColumns.Rows)
                {
                    ColInfo oInfo = new ColInfo();
                    oInfo.Name = oRow.ColumnName;
                    oInfo.Type = oRow.Type;
                    strList.Add(oInfo);
                }
                return strList;
            }
        }

    }
}
